package com.wyh.service.serviceImpl.feemanagementserviceimpl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wyh.domain.dto.feemanagementdto.CollectionverificationDto;
import com.wyh.domain.dto.feemanagementdto.VerificationDataDto;
import com.wyh.domain.po.feemanagementpo.*;
import com.wyh.domain.vo.feemanagementvo.CollectionverificationVo;
import com.wyh.mapper.feemanagementmapper.*;
import com.wyh.service.feemanagementservice.CollectionverificationService;
import com.wyh.utils.feemanagementutils.RandomNumberGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class CollectionverificationServiceImpl extends ServiceImpl<CollectionverificationMapper, Collectionverifications> implements CollectionverificationService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private BillVerificationMapper billVerificationMapper;
    @Autowired
    private PrestorageMapper prestorageMapper;
    @Autowired
    private BillDetailVerificationMapper billDetailVerificationMapper;
    @Autowired
    private InvoiceRecordsMapper invoiceRecordsMapper;
    @Autowired
    private PaymentRecordsMapper paymentRecordsMapper;
    @Autowired
    private CollectionverificationMapper collectionverificationMapper;
    @Autowired
    private PlatformTransactionManager transactionManager;
    @Autowired
    private EnterprisenatureMapper enterprisenatureMapper;
    /**
     * @param page
     * @param collectionverificationDto
     * @deprecated 查询出当前账单所有授权楼盘的账单信息
     */
    @Override
    public CollectionverificationVo getAllByIdAndPage(IPage<Collectionverifications> page, CollectionverificationDto collectionverificationDto,String account) {
        List<CollectionverificationInfo> collectionverificationList = null;
        long total = 0;
        IPage<CollectionverificationInfo> page1 = baseMapper.getAllByIdAndPage(page, collectionverificationDto,account);
        collectionverificationList = page1.getRecords();
        total = page1.getTotal();
        //遍历账单信息判断该账单是否有核销记录
        for (CollectionverificationInfo collectionverificationInfo : collectionverificationList) {
            Collectionverifications collectionverifications = baseMapper.getCollectionverification(collectionverificationInfo.getBillid(), collectionverificationDto,account);
            if (collectionverifications != null) {
                collectionverificationInfo.setWriteoff(collectionverifications.getWriteoff());
                collectionverificationInfo.setVerificationdate(collectionverifications.getVerificationdate());
            } else {
                //没有则手动给核销金额赋值
                collectionverificationInfo.setWriteoff("0");
            }
        }
        return new CollectionverificationVo(collectionverificationList, total);
    }
    /**
     * @param verificationDataDto
     * @deprecated 手动核销核销执行方法
     */
    @Override
    public String verificationBill(VerificationDataDto verificationDataDto,Integer id,String account) {
        DefaultTransactionDefinition definition=new DefaultTransactionDefinition();
        definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus transactionStatus=transactionManager.getTransaction(definition);
        boolean flag1 = false;
        boolean flag2 = false;
        boolean flag3 = false;
        boolean flag4 = false;
        boolean flag5 = false;
        boolean flag6 = false;
        boolean flag7 = false;
        boolean isSuccess = false;
        try {
            //修改收款金额
            if(verificationDataDto.getPaymentrecordsid() != null
                    && verificationDataDto.getPaymentrecordsid() != 0
                    && verificationDataDto.getPaymentrecordsmoney().compareTo(new BigDecimal(0)) > 0){
                QueryWrapper<PaymentRecords> paymentRecordsQueryWrapper = new QueryWrapper<>();
                paymentRecordsQueryWrapper.eq("id",verificationDataDto.getPaymentrecordsid());
                PaymentRecords paymentRecords = paymentRecordsMapper.selectOne(paymentRecordsQueryWrapper);
                List<BillVerification> billVerificationList = verificationDataDto.getBillVerificationList();
                List<Integer> billIds = new ArrayList<>();
                for (BillVerification billVerification : billVerificationList) {
                    billIds.add(billVerification.getBillid());
                }
                QueryWrapper<Billes> billesQueryWrappers = new QueryWrapper<>();
                billesQueryWrappers.in("id",billIds).select("sum(totalarrears) as totalarrears");
                Billes billes1 = billVerificationMapper.selectOne(billesQueryWrappers);
                //只使用了可核销金额
                if(billes1.getTotalarrears().compareTo(verificationDataDto.getPaymentrecordsmoney()) == 0 && paymentRecords.getAmount().compareTo(verificationDataDto.getPaymentrecordsmoney())>=0){
                    paymentRecords.setAmount(paymentRecords.getAmount().subtract(verificationDataDto.getPaymentrecordsmoney()));
                    flag1 = paymentRecordsMapper.updateById(paymentRecords)>0;
                    QueryWrapper<Billes> billesQueryWrapper = new QueryWrapper<>();
                    billesQueryWrapper.in("id",billIds);
                    Billes billes = new Billes();
                    billes.setArrears(new BigDecimal(0));
                    billes.setArrearsstatus(0);
                    billes.setReceivable(new BigDecimal(0));
                    billes.setTotalarrears(new BigDecimal(0));
                    flag2 = billVerificationMapper.update(billes,billesQueryWrapper)>0;
                    for (BillVerification billVerification : billVerificationList) {
                        QueryWrapper<Billdetailes> billdetailesQueryWrapper = new QueryWrapper<>();
                        billdetailesQueryWrapper.eq("billid",billVerification.getBillid()).gt("accountsreceivable",0).orderByAsc("accountsreceivable");
                        List<Billdetailes> billdetailes = billDetailVerificationMapper.selectList(billdetailesQueryWrapper);
                        Billes bill = billVerificationMapper.selectById(billVerification.getBillid());
                        for (Billdetailes billdetaile : billdetailes) {
                            if(billdetaile.getVerificationamount() == null){
                                billdetaile.setVerificationamount(billdetaile.getAccountsreceivable());
                            }else{
                                billdetaile.setVerificationamount(new BigDecimal(billdetaile.getVerificationamount()).add(new BigDecimal(billdetaile.getAccountsreceivable())).toString());
                            }
                            billdetaile.setAccountsreceivable("0");
                            flag3 = billDetailVerificationMapper.updateById(billdetaile)>0;
                        }
                        //生成核销记录
                        Collectionverifications collectionverification;
                        QueryWrapper<Collectionverifications> collectionverificationQueryWrapper = new QueryWrapper<>();
                        collectionverificationQueryWrapper.eq("billid",billVerification.getBillid());
                        List<Collectionverifications> collectionverifications = collectionverificationMapper.selectList(collectionverificationQueryWrapper);
                        //判断该账单在以前有没有核销记录,如果没有则生成新的核销记录
                        if(collectionverifications.isEmpty()){
                            collectionverification = new Collectionverifications();
                            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
                            String accounttime = format.format(bill.getAccounttime());
                            collectionverification.setId(RandomNumberGenerator.generateRandomKey());
                            collectionverification.setAccountingperiod(accounttime);
                            collectionverification.setBillid(bill.getId());
                            collectionverification.setBillnumber(bill.getBillnumber().toString());
                            collectionverification.setCustomername(bill.getCustomername());
                            collectionverification.setPropertyname(bill.getPropertyname());
                            collectionverification.setPayee(bill.getPayee());
                            collectionverification.setArrearsstatus("Y");
                            collectionverification.setArrearsoffees(bill.getTotalarrears().toString());
                            collectionverification.setWriteoff(billVerification.getTotalverificationmoney().toString());
                            collectionverification.setReceivable(bill.getTotalarrears().toString());
                            if(bill.getNotificationstatus() == 1){
                                collectionverification.setNotificationstatus("Y");
                            }
                            collectionverification.setNotificationstatus("N");
                            collectionverification.setIswriteoff("N");
                            if(bill.getTotalarrears().compareTo(new BigDecimal(0)) == 0){
                                collectionverification.setIswriteoff("Y");
                                collectionverification.setVerificationdate(new Date());
                            }
                        }else{
                            //如果有就在以前的核销记录基础上调整欠费详情
                            collectionverifications.sort(Comparator.comparing(Collectionverifications::getArrearsoffees));
                            collectionverification = collectionverifications.get(0);
                            collectionverification.setArrearsoffees("0");
                            collectionverification.setArrearsstatus("N");
                            collectionverification.setIswriteoff("Y");
                            collectionverification.setReceivable("0");
                            collectionverification.setVerificationdate(new Date());
                            collectionverification.setWriteoff(billVerification.getTotalverificationmoney().toString());
                        }
                        //生成核销记录
                        flag5 = collectionverificationMapper.insert(collectionverification)>0;
                        Enterprisenature enterprisenature = enterprisenatureMapper.getEnterprisenatureByUid(account);
                        Invoicerecordes invoicerecordes = new Invoicerecordes();
                        invoicerecordes.setId(RandomNumberGenerator.generateRandomKey());
                        invoicerecordes.setAmount(billVerification.getTotalverificationmoney());
                        invoicerecordes.setBillid(billVerification.getBillid());
                        invoicerecordes.setInvoicingtype(verificationDataDto.getInvoicetype());
                        if(verificationDataDto.getInvoicetype()<=5 && verificationDataDto.getInvoicetype() != 0){
                            invoicerecordes.setSalesside(enterprisenature.getName());
                            invoicerecordes.setType(0);
                        }else if(verificationDataDto.getInvoicetype() > 5){
                            transactionManager.rollback(transactionStatus);
                            return "未匹配类型的开票类型";
                        }else{
                            invoicerecordes.setOwner(verificationDataDto.getCustomerid());
                            invoicerecordes.setAmount(billVerification.getTotalverificationmoney());
                            invoicerecordes.setType(1);
                        }
                        //生成开票记录
                        flag6 = invoiceRecordsMapper.insert(invoicerecordes)>0;
                        verificationDataDto.setPaymentrecordsmoney(new BigDecimal(0));
                        isSuccess = flag1 && flag2 && flag5 && flag6;
                        if(isSuccess){
                            transactionManager.commit(transactionStatus);
                            return "核销成功";
                        }
                    }
                }else{
                    //判断该收款记录的客户使用金额是否大于剩余金额
                    List<PreStorageInfo> preStorageInfoList = new ArrayList<>();
                    for (BillVerification billVerification : verificationDataDto.getBillVerificationList()) {
                        for (BillDetailVerification billDetailVerification : billVerification.getBillDetailVerificationList()) {
                            preStorageInfoList = billDetailVerification.getPreStorageInfoList();
                        }
                    }
                    //可核销金额和预存都使用了
                    if(paymentRecords.getAmount().compareTo(verificationDataDto.getPaymentrecordsmoney()) > 0 && preStorageInfoList.get(0).getPrestorageusedmoney().compareTo(new BigDecimal(0))>0){
                        paymentRecords.setAmount(paymentRecords.getAmount().subtract(verificationDataDto.getPaymentrecordsmoney()));
                        for (BillVerification billVerification : billVerificationList) {
                            if(paymentRecords.getAmount().compareTo(billVerification.getTotalverificationmoney()) >0 ){
                                QueryWrapper<Billes> billesQueryWrapper = new QueryWrapper<>();
                                billesQueryWrapper.eq("id",billVerification.getBillid());
                                Billes billes = billVerificationMapper.selectOne(billesQueryWrapper);
                                billes.setArrears(new BigDecimal(0));
                                billes.setArrearsstatus(0);
                                billes.setReceivable(new BigDecimal(0));
                                billes.setTotalarrears(new BigDecimal(0));
                                Billes bill = billVerificationMapper.selectById(billVerification.getBillid());
                                flag2 = billVerificationMapper.updateById(billes)>0;
                                if(bill.getTotalarrears().compareTo(billVerification.getTotalverificationmoney()) == 0){
                                    for (BillDetailVerification billDetailVerification : billVerification.getBillDetailVerificationList()) {
                                            for (PreStorageInfo preStorageInfo : billDetailVerification.getPreStorageInfoList()) {
                                                QueryWrapper<PreStorages> preStoragesQueryWrapper = new QueryWrapper<>();
                                                preStoragesQueryWrapper.eq("id",preStorageInfo.getPrestorageid());
                                                PreStorages preStorages = prestorageMapper.selectOne(preStoragesQueryWrapper);
                                                QueryWrapper<Billdetailes> billdetailesQueryWrapper = new QueryWrapper<>();
                                                billdetailesQueryWrapper.eq("billid",billVerification.getBillid()).eq("billingitemsid",preStorages.getSubject()).gt("accountsreceivable",0).orderByAsc("accountsreceivable");
                                                List<Billdetailes> billdetailes = billDetailVerificationMapper.selectList(billdetailesQueryWrapper);
                                                for (Billdetailes billdetaile : billdetailes) {
                                                    if (preStorages != null) {
                                                        //比较预存金额和账单金额的大小
                                                        if (preStorageInfo.getPrestorageusedmoney().compareTo(new BigDecimal(billdetaile.getAccountsreceivable())) >= 0) {
                                                            preStorages.setId(RandomNumberGenerator.generateRandomKey());
                                                            preStorages.setBeforechange(preStorages.getAfterchange());
                                                            preStorages.setChangeamount(new BigDecimal(billdetaile.getAccountsreceivable()));
                                                            preStorages.setAfterchange(preStorages.getAfterchange().subtract(new BigDecimal(billdetaile.getAccountsreceivable())));
                                                            preStorages.setChangetype(Integer.parseInt(billdetaile.getBillingitemsid()));
                                                            preStorages.setUserid(id);
                                                            preStorages.setOperationtime(new Date());
                                                            if (billdetaile.getPredepositoffset() == null) {
                                                                billdetaile.setPredepositoffset(billdetaile.getAccountsreceivable());
                                                            } else {
                                                                billdetaile.setPredepositoffset(new BigDecimal(billdetaile.getPredepositoffset()).add(new BigDecimal(billdetaile.getAccountsreceivable())).toString());
                                                            }
                                                            if (billdetaile.getVerificationamount() == null) {
                                                                billdetaile.setVerificationamount(billdetaile.getAccountsreceivable());
                                                            } else {
                                                                billdetaile.setVerificationamount(new BigDecimal(billdetaile.getPredepositoffset()).add(new BigDecimal(billdetaile.getAccountsreceivable())).toString());
                                                            }
                                                            billdetaile.setAccountsreceivable("0");
                                                            preStorageInfo.setPrestorageusedmoney(preStorageInfo.getPrestorageusedmoney().subtract(new BigDecimal(billdetaile.getAccountsreceivable())));
                                                        } else {
                                                            if (preStorageInfo.getPrestorageusedmoney().compareTo(new BigDecimal(0)) > 0) {
                                                                if (billdetaile.getPredepositoffset() == null) {
                                                                    billdetaile.setPredepositoffset(preStorageInfo.getPrestorageusedmoney().toString());
                                                                } else {
                                                                    billdetaile.setPredepositoffset(new BigDecimal(billdetaile.getPredepositoffset()).add(preStorageInfo.getPrestorageusedmoney()).toString());
                                                                }
                                                                if (billdetaile.getVerificationamount() == null) {
                                                                    billdetaile.setVerificationamount(preStorageInfo.getPrestorageusedmoney().toString());
                                                                } else {
                                                                    billdetaile.setVerificationamount(new BigDecimal(billdetaile.getPredepositoffset()).add(preStorageInfo.getPrestorageusedmoney()).toString());
                                                                }
                                                                preStorages.setId(RandomNumberGenerator.generateRandomKey());
                                                                preStorages.setBeforechange(preStorages.getAfterchange());
                                                                preStorages.setChangeamount(preStorageInfo.getPrestorageusedmoney());
                                                                preStorages.setAfterchange(preStorages.getAfterchange().subtract(preStorages.getChangeamount()));
                                                                preStorages.setChangetype(Integer.parseInt(billdetaile.getBillingitemsid()));
                                                                preStorages.setUserid(id);
                                                                preStorages.setOperationtime(new Date());
                                                                billdetaile.setAccountsreceivable(new BigDecimal(billdetaile.getAccountsreceivable()).subtract(preStorageInfo.getPrestorageusedmoney()).toString());
                                                                preStorageInfo.setPrestorageusedmoney(new BigDecimal(0));
                                                            }
                                                        }
                                                        //修改账单详情信息
                                                        flag3 = billDetailVerificationMapper.updateById(billdetaile) > 0;
                                                        //修改预存的信息
                                                        flag4 = prestorageMapper.insert(preStorages) > 0;
                                                        //获取新生成的预存记录
                                                        preStorages = prestorageMapper.selectById(preStorages.getId());
                                                    }
                                                }
                                            }
                                            //将账单详情剩余的应收金额用可核销金额核销
                                            QueryWrapper<Billdetailes> billdetailesQueryWrapper = new QueryWrapper<>();
                                            billdetailesQueryWrapper.eq("billid",billVerification.getBillid()).gt("accountsreceivable",0);
                                        List<Billdetailes> billdetailes = billDetailVerificationMapper.selectList(billdetailesQueryWrapper);
                                        for (Billdetailes billdetaile : billdetailes) {
                                            if(billdetaile.getVerificationamount() == null){
                                                billdetaile.setVerificationamount(billdetaile.getAccountsreceivable());
                                            }else{
                                                billdetaile.setVerificationamount(new BigDecimal(billdetaile.getVerificationamount()).add(new BigDecimal(billdetaile.getAccountsreceivable())).toString());
                                            }
                                            billdetaile.setAccountsreceivable("0");
                                            flag5 = billDetailVerificationMapper.updateById(billdetaile)>0;
                                        }
                                        //生成核销记录
                                        Collectionverifications collectionverification;
                                        QueryWrapper<Collectionverifications> collectionverificationQueryWrapper = new QueryWrapper<>();
                                        collectionverificationQueryWrapper.eq("billid",billVerification.getBillid());
                                        List<Collectionverifications> collectionverifications = collectionverificationMapper.selectList(collectionverificationQueryWrapper);
                                        //判断该账单在以前有没有核销记录,如果没有则生成新的核销记录
                                        if(collectionverifications.isEmpty()){
                                            collectionverification = new Collectionverifications();
                                            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
                                            String accounttime = format.format(billes.getAccounttime());
                                            collectionverification.setId(RandomNumberGenerator.generateRandomKey());
                                            collectionverification.setAccountingperiod(accounttime);
                                            collectionverification.setBillid(billes.getId());
                                            collectionverification.setBillnumber(billes.getBillnumber().toString());
                                            collectionverification.setCustomername(billes.getCustomername());
                                            collectionverification.setPropertyname(billes.getPropertyname());
                                            collectionverification.setPayee(billes.getPayee());
                                            collectionverification.setArrearsstatus("Y");
                                            collectionverification.setArrearsoffees(billes.getTotalarrears().toString());
                                            collectionverification.setWriteoff(billVerification.getTotalverificationmoney().toString());
                                            collectionverification.setReceivable(billes.getTotalarrears().toString());
                                            if(billes.getNotificationstatus() == 1){
                                                collectionverification.setNotificationstatus("Y");
                                            }
                                            collectionverification.setNotificationstatus("N");
                                            collectionverification.setIswriteoff("N");
                                            if(billes.getTotalarrears().compareTo(new BigDecimal(0)) == 0){
                                                collectionverification.setIswriteoff("Y");
                                                collectionverification.setVerificationdate(new Date());
                                            }
                                        }else{
                                            //如果有就在以前的核销记录基础上调整欠费详情
                                            collectionverifications.sort(Comparator.comparing(Collectionverifications::getArrearsoffees));
                                            collectionverification = collectionverifications.get(0);
                                            collectionverification.setArrearsoffees("0");
                                            collectionverification.setArrearsstatus("N");
                                            collectionverification.setIswriteoff("Y");
                                            collectionverification.setReceivable("0");
                                            collectionverification.setVerificationdate(new Date());
                                            collectionverification.setWriteoff(billVerification.getTotalverificationmoney().toString());
                                        }
                                        //生成核销记录
                                        flag6 = collectionverificationMapper.insert(collectionverification)>0;
                                        Enterprisenature enterprisenature = enterprisenatureMapper.getEnterprisenatureByUid(account);
                                        Invoicerecordes invoicerecordes = new Invoicerecordes();
                                        invoicerecordes.setId(RandomNumberGenerator.generateRandomKey());
                                        invoicerecordes.setAmount(billVerification.getTotalverificationmoney());
                                        invoicerecordes.setBillid(billVerification.getBillid());
                                        invoicerecordes.setInvoicingtype(verificationDataDto.getInvoicetype());
                                        if(verificationDataDto.getInvoicetype()<=5 && verificationDataDto.getInvoicetype() != 0){
                                            invoicerecordes.setSalesside(enterprisenature.getName());
                                            invoicerecordes.setType(0);
                                        }else if(verificationDataDto.getInvoicetype() > 5){
                                            transactionManager.rollback(transactionStatus);
                                            return "未匹配类型的开票类型";
                                        }else{
                                            invoicerecordes.setOwner(verificationDataDto.getCustomerid());
                                            invoicerecordes.setAmount(billVerification.getTotalverificationmoney());
                                            invoicerecordes.setType(1);
                                        }
                                        //生成开票记录
                                        flag7 = invoiceRecordsMapper.insert(invoicerecordes)>0;
                                    }
                                }else if(bill.getTotalarrears().compareTo(billVerification.getTotalverificationmoney()) > 0){
                                    transactionManager.rollback(transactionStatus);
                                    return "使用金额不能小于账单欠费金额"+bill.getTotalarrears()+"元";
                                }else{
                                    transactionManager.rollback(transactionStatus);
                                    return "使用金额不能大于账单欠费金额"+bill.getTotalarrears()+"元";
                                }
                            }else{
                                transactionManager.rollback(transactionStatus);
                                return "可核销金额不足。";
                            }
                        }
                        //判断核销金额字段是否为空
                        if(paymentRecords.getUsedamount() != null) {
                            paymentRecords.setUsedamount(paymentRecords.getUsedamount().add(verificationDataDto.getPaymentrecordsmoney()));
                        }else{
                            paymentRecords.setUsedamount(verificationDataDto.getPaymentrecordsmoney());
                        }
                        if(paymentRecords.getAmount().compareTo(verificationDataDto.getPaymentrecordsmoney()) == 0){
                            paymentRecords.setUserstate(1L);
                        }else{
                            paymentRecords.setUserstate(0L);
                        }
                        //判断是否修改成功
                        flag1 = paymentRecordsMapper.updateById(paymentRecords)>0;
                        isSuccess = flag1 && flag2 && flag3 && flag4 && flag5 && flag6 && flag7;
                        if(isSuccess){
                            transactionManager.commit(transactionStatus);
                            return "核销成功";
                        }
                    }else{
                        transactionManager.rollback(transactionStatus);
                        return "收款记录使用金额不能超过可核销金额";
                    }
                }

            }
            //没有使用可核销金额(只使用了预存抵扣)
            if(verificationDataDto.getPaymentrecordsmoney().compareTo(new BigDecimal(0)) == 0){
                //获取前端的核销信息详情
                List<BillVerification> billVerificationList = verificationDataDto.getBillVerificationList();
                for (BillVerification billVerification : billVerificationList) {
                    QueryWrapper<Billes> billQueryWrapper = new QueryWrapper<>();
                    billQueryWrapper.eq("id",billVerification.getBillid());
                    Billes billes = billVerificationMapper.selectOne(billQueryWrapper);
                    //判断该账单的欠款金额是否等于前端传递过来的账单金额
                    if(billes.getTotalarrears().compareTo(billVerification.getTotalverificationmoney()) == 0){
                        billes.setArrears(new BigDecimal(0));
                        billes.setReceivable(new BigDecimal(0));
                        billes.setTotalarrears(new BigDecimal(0));
                        billes.setArrearsstatus(0);
                        //修改账单欠费详情
                        flag2 = billVerificationMapper.updateById(billes)>0;
                    }else if(billes.getTotalarrears().compareTo(billVerification.getTotalverificationmoney()) >= 0){
                        transactionManager.rollback(transactionStatus);
                        return "该笔收款记录可核销金额不足以核销该笔账单，请使用预存或更换收款记录进行核销";
                    }else{
                        transactionManager.rollback(transactionStatus);
                        return "账单已核销";
                    }
                    //获取预存使用详情
                    List<BillDetailVerification> billDetailVerificationList = billVerification.getBillDetailVerificationList();
                    for (BillDetailVerification billDetailVerification : billDetailVerificationList) {
                        //根据客户使用预存对对应的账单详情进行冲抵
                        for (PreStorageInfo preStorageInfo : billDetailVerification.getPreStorageInfoList()) {
                            QueryWrapper<PreStorages> preStorageQueryWrapper = new QueryWrapper<>();
                            preStorageQueryWrapper.eq("id",preStorageInfo.getPrestorageid());
                            PreStorages preStorages = prestorageMapper.selectOne(preStorageQueryWrapper);
                            QueryWrapper<Billdetailes> billdetailsQueryWrapper = new QueryWrapper<>();
                            billdetailsQueryWrapper.eq("billid",billVerification.getBillid()).eq("billingresourcesid",billDetailVerification.getResourceid()).eq("billingitemsid",preStorageInfo.getSubject()).orderByAsc("accountsreceivable");
                            //查询出属于同一个账单的同一个计费项目的账单详情进行预存冲抵
                            List<Billdetailes> billdetailesList = billDetailVerificationMapper.selectList(billdetailsQueryWrapper);
                            for (Billdetailes billdetailes : billdetailesList) {
                                if(Integer.parseInt(billdetailes.getBillingitemsid()) == preStorageInfo.getSubject()){
                                    if(preStorages != null) {
                                        if (preStorageInfo.getPrestorageusedmoney().compareTo(new BigDecimal(billdetailes.getAccountsreceivable())) >= 0) {
                                            //修改该预存科目的预存金额
                                            preStorages.setBeforechange(preStorages.getAfterchange());
                                            preStorages.setChangeamount(new BigDecimal(billdetailes.getAccountsreceivable()));
                                            preStorages.setAfterchange(preStorages.getAfterchange().subtract(new BigDecimal(billdetailes.getAccountsreceivable())));
                                            preStorages.setOperationtime(new Date());
                                            preStorages.setChangetype(Integer.parseInt(billdetailes.getBillingitemsid()));
                                            billdetailes.setAccountsreceivable("0");
                                            if (billdetailes.getVerificationamount() != null) {
                                                billdetailes.setVerificationamount(new BigDecimal(billdetailes.getVerificationamount()).add(preStorages.getChangeamount()).toString());
                                            }else{
                                                billdetailes.setVerificationamount(preStorages.getChangeamount().toString());
                                            }
                                            if (billdetailes.getPredepositoffset() != null) {
                                                billdetailes.setPredepositoffset(new BigDecimal(billdetailes.getPredepositoffset()).add(preStorages.getChangeamount()).toString());
                                            } else{
                                                billdetailes.setPredepositoffset(preStorages.getChangeamount().toString());
                                            }
                                            //修改前端传递预存的剩余金额
                                            preStorageInfo.setPrestorageusedmoney(preStorageInfo.getPrestorageusedmoney().subtract(new BigDecimal(billdetailes.getAccountsreceivable())));
                                            preStorages.setId(RandomNumberGenerator.generateRandomKey());
                                            preStorages.setUserid(id);
                                        } else {
                                            //如果该比预存剩余金额不足以抵扣全部的账单详情应收金额则将剩余的应收金额使用收款记录进行核销
                                            if (billdetailes.getPredepositoffset() != null) {
                                                billdetailes.setPredepositoffset(new BigDecimal(billdetailes.getPredepositoffset()).add(preStorageInfo.getPrestorageusedmoney()).toString());
                                            }
                                            preStorages.setBeforechange(preStorages.getAfterchange());
                                            preStorages.setChangeamount(preStorageInfo.getPrestorageusedmoney());
                                            preStorages.setAfterchange(preStorages.getAfterchange().subtract(preStorageInfo.getPrestorageusedmoney()));
                                            if(billdetailes.getPredepositoffset() == null){
                                                billdetailes.setPredepositoffset(preStorageInfo.getPrestorageusedmoney().toString());
                                            }else{
                                                billdetailes.setPredepositoffset(new BigDecimal(billdetailes.getPredepositoffset()).add(preStorageInfo.getPrestorageusedmoney()).toString());
                                            }
                                            billdetailes.setAccountsreceivable("0");
                                            if (billdetailes.getVerificationamount() != null) {
                                                billdetailes.setVerificationamount(new BigDecimal(billdetailes.getVerificationamount()).add(preStorageInfo.getPrestorageusedmoney()).toString());
                                            }else{
                                                billdetailes.setVerificationamount(preStorageInfo.getPrestorageusedmoney().toString());
                                            }
                                            preStorages.setChangetype(Integer.parseInt(billdetailes.getBillingitemsid()));
                                            preStorages.setOperationtime(new Date());
                                            preStorages.setUserid(id);
                                            preStorages.setId(RandomNumberGenerator.generateRandomKey());
                                            preStorageInfo.setPrestorageusedmoney(new BigDecimal(0));
                                        }
                                        //修改账单详情信息
                                        flag3 = billDetailVerificationMapper.updateById(billdetailes)>0;
                                        //修改预存的信息
                                        flag4 = prestorageMapper.insert(preStorages)>0;
                                        preStorages = prestorageMapper.selectById(preStorages.getId());
                                    }
                                }else{
                                    transactionManager.rollback(transactionStatus);
                                    return "没有找到该笔预存";
                                }
                            }

                        }
                    }
                    //生成核销记录
                    Collectionverifications collectionverification;
                    QueryWrapper<Collectionverifications> collectionverificationQueryWrapper = new QueryWrapper<>();
                    collectionverificationQueryWrapper.eq("billid",billVerification.getBillid());
                    List<Collectionverifications> collectionverifications = collectionverificationMapper.selectList(collectionverificationQueryWrapper);
                    //判断该账单在以前有没有核销记录,如果没有则生成新的核销记录
                    if(collectionverifications.isEmpty()){
                        collectionverification = new Collectionverifications();
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
                        String accounttime = format.format(billes.getAccounttime());
                        collectionverification.setId(RandomNumberGenerator.generateRandomKey());
                        collectionverification.setAccountingperiod(accounttime);
                        collectionverification.setBillid(billes.getId());
                        collectionverification.setBillnumber(billes.getBillnumber().toString());
                        collectionverification.setCustomername(billes.getCustomername());
                        collectionverification.setPropertyname(billes.getPropertyname());
                        collectionverification.setPayee(billes.getPayee());
                        collectionverification.setArrearsstatus("Y");
                        collectionverification.setArrearsoffees(billes.getTotalarrears().toString());
                        collectionverification.setWriteoff(billVerification.getTotalverificationmoney().toString());
                        collectionverification.setReceivable(billes.getTotalarrears().toString());
                        if(billes.getNotificationstatus() == 1){
                            collectionverification.setNotificationstatus("Y");
                        }
                        collectionverification.setNotificationstatus("N");
                        collectionverification.setIswriteoff("N");
                        if(billes.getTotalarrears().compareTo(new BigDecimal(0)) == 0){
                            collectionverification.setIswriteoff("Y");
                            collectionverification.setVerificationdate(new Date());
                        }
                    }else{
                        //如果有就在以前的核销记录基础上调整欠费详情
                        collectionverifications.sort(Comparator.comparing(Collectionverifications::getArrearsoffees));
                        collectionverification = collectionverifications.get(0);
                        collectionverification.setArrearsoffees("0");
                        collectionverification.setArrearsstatus("N");
                        collectionverification.setIswriteoff("Y");
                        collectionverification.setReceivable("0");
                        collectionverification.setVerificationdate(new Date());
                        collectionverification.setWriteoff(billVerification.getTotalverificationmoney().toString());
                    }
                    //生成核销记录
                    flag5 = collectionverificationMapper.insert(collectionverification)>0;
                    Enterprisenature enterprisenature = enterprisenatureMapper.getEnterprisenatureByUid(account);
                    Invoicerecordes invoicerecordes = new Invoicerecordes();
                    invoicerecordes.setId(RandomNumberGenerator.generateRandomKey());
                    invoicerecordes.setAmount(billVerification.getTotalverificationmoney());
                    invoicerecordes.setBillid(billVerification.getBillid());
                    invoicerecordes.setInvoicingtype(verificationDataDto.getInvoicetype());
                    if(verificationDataDto.getInvoicetype()<=5 && verificationDataDto.getInvoicetype() != 0){
                        invoicerecordes.setSalesside(enterprisenature.getName());
                        invoicerecordes.setType(0);
                    }else if(verificationDataDto.getInvoicetype() > 5){
                        transactionManager.rollback(transactionStatus);
                        return "未匹配类型的开票类型";
                    }else{
                        invoicerecordes.setOwner(verificationDataDto.getCustomerid());
                        invoicerecordes.setAmount(billVerification.getTotalverificationmoney());
                        invoicerecordes.setType(1);
                    }
                    //生成开票记录
                    flag6 = invoiceRecordsMapper.insert(invoicerecordes)>0;
                }
                isSuccess = flag2 && flag3 && flag4 && flag5 && flag6;
                if(isSuccess){
                    transactionManager.commit(transactionStatus);
                    return "核销成功";
                }
            }

        } catch (RuntimeException e) {
            log.error("手动核销出错了");
            transactionManager.rollback(transactionStatus);
            throw new RuntimeException(e);
        }
        return "核销失败";
    }
}
